#include "bt_flash.h"
#include "bt_wdt.h"
#include "bt_timer.h"
#include "bt_rs485.h"
#include "bt_task.h"
#include "delay.h"
#include "EEPROM.h"

#define IAP_DEVADDR_ADDRESS (0x0800)

unsigned char AddrFlag = 0xaa;
unsigned char temp;



// 在位状态枚举
enum Gun_status{
    OFF = 0x90,
    ERRO_RedLight = 0x91,
    ERRO_KEY = 0x92,
    ON = 0x93,
    DARK = 0x94
};

typedef struct
{
    enum Gun_status status;
    unsigned char addr;
    unsigned char level_high;
    unsigned char level_low;
    unsigned char Mode;
}bt_task_manager_s;

static bt_task_manager_s data g_task_manager = {0};

static unsigned char Led_Mode = 0; // 0:正常模式 1：还取枪模式
static enum Gun_status now_status = 0;  // 当前状态

static unsigned short time_count = 0; // 30s计数器   在定时器中计数 每50ms加一 共计600次
static unsigned char led_flag = 0;      // 亮灭切换


void LED_Flag_Switch(unsigned char value)
{
    led_flag = value;
}

void Time_Count_Plus(void)
{
    time_count++;
}

void Time_Count_Reset(void)
{
    time_count = 0;
}

u8 GetKEY_IN_Status(void)
{
	return P37;
}

u8 GetREC_LED_Status(void)
{
	return P36;
}

void LightGreen(u8 value)
{
	P33 = value;
}

void LightRed(u8 value)
{
	P32 = value;
}


/**
* @brief 框架必须实现: RS485数据解析
 * @param  msg：缓存区数据
 * @param  len:数据长度
 * @note
 * @retval
 */
void rs485_parser(unsigned char *msg, int len)
{
    bt_task_manager_s *manager = &g_task_manager;
    unsigned char i = 0;
    unsigned char data smsg[9];
    // 长度判断
    if (len != 9)
    {
        return;
    }
    // 校验
    if ((msg[7] == 0x30) && msg[8] == 0x55 || bt_rs485_check_xor(msg, 8) == msg[8])
    {
        if ((msg[2] == manager->addr) && (msg[3] == 0x33))              /*获取枪卡状态*/
        {
            smsg[0] = 0xaa;
            smsg[1] = 0xaa;
            smsg[2] = manager->addr; // 地址
            smsg[3] = manager->status; // 状态
            smsg[4] = 0x00;
            smsg[5] = 0x30;
            smsg[6] = 0x04;
            smsg[7] = 0x30;
            smsg[8] = bt_rs485_check_xor(smsg, 8);
            bt_rs485_send_datas((unsigned char *)&smsg, 9);
        }
        if ((msg[2] == 0xFF) && (msg[3] == 0x40) && (msg[6] == 0x80)) // 设置地址
        {
            smsg[0] = 0xaa;
            smsg[1] = 0xaa;

            manager->addr= msg[4];  // 设置地址
            /* 保存地址到flash */
            EEPROM_SectorErase((unsigned int)IAP_DEVADDR_ADDRESS);
            EEPROM_write_n((unsigned int)IAP_DEVADDR_ADDRESS, (unsigned char *)&AddrFlag, 1);
            EEPROM_write_n((unsigned int)(IAP_DEVADDR_ADDRESS + 1), (unsigned char *)&manager->addr, 1);
            
            smsg[2] = msg[2]; // 板号
            smsg[3] = msg[3]; // 命令
            smsg[4] = manager->addr; // 地址
            smsg[5] = msg[5];
            smsg[6] = msg[6];
            smsg[7] = msg[7];
            smsg[8] = bt_rs485_check_xor(smsg, 8);
            bt_rs485_send_datas((unsigned char *)&smsg, 9);
        }

        // if ((msg[2] == manager->addr) && (msg[3] == 0x34) && (msg[6] == 0x40))   // 设置版本                   // 设置版本
        // {
        //     smsg[0] = 0xaa;
        //     smsg[1] = 0xaa;
        //     smsg[2] = manager->addr;
        //     manager->level_high = msg[4];
        //     manager->level_low  = msg[5];
        //     smsg[3] = msg[3];
        //     smsg[4] = msg[4];
        //     smsg[5] = msg[5];
        //     smsg[6] = msg[6];
        //     smsg[7] = msg[7];
        //     smsg[8] = bt_rs485_check_xor(smsg, 8);
        //     bt_rs485_send_datas((unsigned char *)&smsg, 9);
        // }
        // if ((msg[2] == manager->addr) && (msg[3] == 0x38) && (msg[6] == 0x80))  //查询版本
        // {
        //     smsg[0] = 0xaa;
        //     smsg[1] = 0xaa;
        //     smsg[2] = manager->addr;
        //     smsg[3] = msg[3];
        //     smsg[4] = manager->level_high;
        //     smsg[5] = manager->level_low;
        //     smsg[6] = msg[6];
        //     smsg[7] = msg[7];
        //     smsg[8] = bt_rs485_check_xor(smsg, 8);
        //     bt_rs485_send_datas((unsigned char *)&smsg, 9);
        // }
        // if ((msg[2] == manager->addr) && (msg[3] == 0x31))  // 取枪指令
        // {
        //     manager->Mode = 1;
        //     now_status = ON;
        //     smsg[0] = 0xaa;
        //     smsg[1] = 0xaa;
        //     smsg[2] = manager->addr; // 地址
        //     smsg[3] = manager->status; // 状态
        //     smsg[4] = 0x00;
        //     smsg[5] = 0x30;
        //     smsg[6] = 0x04;
        //     smsg[7] = 0x30;
        //     smsg[8] = bt_rs485_check_xor(smsg, 8);
        //     bt_rs485_send_datas((unsigned char *)&smsg, 9);
        // }
        // if ((msg[2] == manager->addr) && (msg[3] == 0x32))  // 还枪指令
        // {
        //     manager->Mode = 1;
        //     now_status = OFF;
        //     smsg[0] = 0xaa;
        //     smsg[1] = 0xaa;
        //     smsg[2] = manager->addr; // 地址
        //     smsg[3] = manager->status; // 状态
        //     smsg[4] = 0x00;
        //     smsg[5] = 0x30;
        //     smsg[6] = 0x04;
        //     smsg[7] = 0x30;
        //     smsg[8] = bt_rs485_check_xor(smsg, 8);
        //     bt_rs485_send_datas((unsigned char *)&smsg, 9);
        // }
        // if ((msg[2] == manager->addr) && (msg[3] == 0x7F))  // 终止还取枪指令
        // {
        //     manager->Mode = 0;
        //     smsg[0] = 0xaa;
        //     smsg[1] = 0xaa;
        //     smsg[2] = manager->addr;
        //     smsg[3] = msg[3];
        //     smsg[4] = msg[4];
        //     smsg[5] = msg[5];
        //     smsg[6] = msg[6];
        //     smsg[7] = msg[7];
        //     smsg[8] = bt_rs485_check_xor(smsg, 8);
        //     bt_rs485_send_datas((unsigned char *)&smsg, 9);
        // }
        
    }
}

/**
 * 获取当前红外微动的状态
 */
void Get_Switch_Status(void)
{
    bt_task_manager_s *manager = &g_task_manager;

    if (GetREC_LED_Status() && GetKEY_IN_Status())
    {
        manager->status = OFF;
    }
    else if(GetREC_LED_Status() && !GetKEY_IN_Status())
    {
        manager->status = ERRO_KEY;
    }
    else if(!GetREC_LED_Status() && GetKEY_IN_Status())
    {
        manager->status = ERRO_RedLight;
    }
    else if(!GetREC_LED_Status() && !GetKEY_IN_Status())
    {
        manager->status = ON;
    }
}

/**
 * 设置灯光状态
 */
void Set_LED_Status(enum Gun_status status)
{
    switch (status)
    {
        case ON:
            LightRed(0);
            LightGreen(1);
            break;
        case ERRO_KEY:
            LightGreen(0);
            LightRed(1);
            break;
        case ERRO_RedLight:
            LightGreen(0);
            LightRed(1);
            break;
        case OFF:
            LightGreen(0);
            LightRed(1);
            break;
        case DARK:
            LightGreen(0);
            LightRed(0);
            break;
        default:
            break;
    }
}


/**
 * @brief  框架必须实现�?10ms定时器循�?
 * @note
 * @retval
 */
void bt_timer_loop(void)
{
    static unsigned char timer_cnt = 0; //50毫秒定时器计数
    bt_task_manager_s *manager = &g_task_manager;
    if (manager->Mode == 1)             // 还取枪模式下计数30s（每50ms计数一次）并切换led亮灭
    {
        timer_cnt++;
        if (timer_cnt == 5)
        {
            timer_cnt = 0;
            Time_Count_Plus();
            if (led_flag == 0)
            {
                LED_Flag_Switch(1);
            }
            else if (led_flag == 1)
            {
                LED_Flag_Switch(0);
            }
        }
    }
    
}

void bt_task_loop(void)
{
    bt_task_manager_s *manager = &g_task_manager;
    unsigned char msg[5] = {0xaa, 0xaa, 0x00, 0x00, 0x00};
    while (1)
    {
        bt_wdt_feed();
        if (manager->Mode == 0)
        {
            Get_Switch_Status();
            Set_LED_Status(manager->status);
        }
        else if (manager->Mode == 1)
        {
            Get_Switch_Status();
            if ((manager->status == now_status) && (time_count < 600))      // 状态没有变化 且在30s内 闪烁 
            {
                if (led_flag == 0)
                {
                    Set_LED_Status(DARK);
                }
                else if (led_flag == 1)
                {
                    Set_LED_Status(now_status);
                }
            }
            else if ((manager->status != now_status) || (time_count >= 600)) // 状态变化 或者 超过30s 停止闪烁 退出
            {
                manager->Mode = 0;
                Time_Count_Reset();
            }
        }
        // bt_rs485_loop();
        
    }
    
}

void bt_task_init(void)
{
    bt_task_manager_s *manager = &g_task_manager;
    manager->Mode = 0;
	/* 获取flash中的地址信息 */
	EEPROM_read_n(IAP_DEVADDR_ADDRESS, (unsigned char *)&temp, 1);
	if (temp == AddrFlag)
	{
		EEPROM_read_n(IAP_DEVADDR_ADDRESS + 1, (unsigned char *)&temp, 1);
		manager->addr = temp;
	}
	else
	{
		/* flash中没有地址 则赋一个初始地址 0xFF*/
		manager->addr = 0xFF;
	}
}